package com.yantu.util;
import com.yantu.bean.User;
import io.jsonwebtoken.*;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Map;

@Component
public class JWTUtil {
    /**
     * 自定义秘钥
     * */
    private static String sign;

    /**
     * jwtToken的默认有效时间 单位分钟
     * */
    private static int expireTime;

    @Value("${jwt.sign}")
    public void setSign(String sign1){
        JWTUtil.sign = sign1;
    }

    @Value("${jwt.expireTime}")
    public void setExpireTime(int expireTime1){
        JWTUtil.expireTime = expireTime1;
    }

    /**
     * pc端生成jwt token
     * @param map  要存放负载信息
     * */
    public static String createJwtTokenpc(Map<String,Object> map){
        Date nowDate = new Date();
        return  Jwts.builder()
                .setClaims(map) //放入payLoad部分的信息
                .signWith(SignatureAlgorithm.HS512,sign)
                .compact();

    }
    /**
     * 从令牌中获取数据,就是payLoad部分存放的数据。如果jwt被改，该函数会直接抛出异常
     * @param token  令牌
     * */
    public static Claims  parseToken(String token){
        System.out.println(token);
        return Jwts.parser()
                .setSigningKey(sign)
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 验证用户信息
     * @param token  jwtToken
     * */
    public static User verifyJwtToken(String token){
        Claims claims = parseToken(token);
        System.out.println("claims:::"+claims.toString());
        String id = String.valueOf(claims.get("id"));
        System.out.println("id:::"+id);
        RedisUtils redisUtils = new RedisUtils();
        //从redis中获取用户信息
        Object user = redisUtils.getValue(id);
        User user1 = (User) user;
        return user1 ;
    }


    /**
     * 刷新令牌时间，刷新redis缓存时间
     * @param  user 用户信息
     * */
    public static void refreshToken(User user){
        //重新设置User对象的过期时间，再刷新缓存
        user.setExpiretime(System.currentTimeMillis()+1000L * 60 * expireTime);

        RedisUtils redisUtils = new RedisUtils();
        redisUtils.saveValueTime(user.getId()+"",user,expireTime);
    }

    /**
     * 设置用户的登录时间和令牌有效时间
     * @param user
     * @return
     */
    public static User setTime(User user){
        user.setExpiretime(System.currentTimeMillis()+1000L * 60 * expireTime);
        user.setLogintime(System.currentTimeMillis());
        return user;
    }

//微信配置
    /**
     * 微信端生成jwt token
     * @param  session
     * */

    public static String getToken(String session){
        Date nowDate = new Date();
        //过期时间
        Date expireDate = new Date(nowDate.getTime() + expireTime * 1000);
        return Jwts.builder()
                .setHeaderParam("typ","JWT")
                .setSubject(session)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512,sign)
                .compact();

    }

    /**
     * 从token中获取自定义登录态session后解密获取openid
     * @param token
     * @return
     */
    public String getOpenidFromToken(String token){
        String openid;
        String session;
        try{
            //解析token获取session
            Claims cliams = getCliamByToken(token);
            session = cliams.getSubject();
            //解密session
            EncryptUtil encryptUtil = new EncryptUtil();
            String jsonString = encryptUtil.decrypt(session);
            JSONObject jsonObject = JSONObject.fromObject(jsonString);
            openid = jsonObject.getString("openid");
            return openid;
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 从token中获取荷载
     * @param token
     * @return
     */
    public Claims getCliamByToken(String token){
        try{
            return Jwts.parser()
                    .setSigningKey(sign)
                    .parseClaimsJws(token)
                    .getBody();
        }
        catch (Exception e){
            return null;
        }
    }

    /**
     * 校验token
     * @param token
     * @return
     */
    public void verifyToken(String token){
        //在拦截器抛出异常
        Jwts.parser().setSigningKey(sign).parseClaimsJws(token).getBody();
    }



}
